﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Windows.UI.Xaml;

namespace MetroToolbox.Collections
{
    public class DependencyObjectCollection<T> : DependencyObject, IList<T>, ICollection<T>, IEnumerable<T>, IList, ICollection, IEnumerable, INotifyCollectionChanged
    {
        private ObservableCollection<T> _collection;

        public DependencyObjectCollection()
        {
            _collection = new ObservableCollection<T>();
            _collection.CollectionChanged += OnCollectionChanged;
        }

        private void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (CollectionChanged != null)
            {
                CollectionChanged(this, e);
            }
        }

        // ******************************************************************** 
        // Begin INotifyCollectionChanged Implementation
        // ******************************************************************** 
        public event NotifyCollectionChangedEventHandler CollectionChanged;
        // ******************************************************************** 
        // End INotifyCollectionChanged Implementation
        // ******************************************************************** 

        // ******************************************************************** 
        // Begin ICollection<T> Implementation
        // ******************************************************************** 
        public void Add(T item)
        {
            _collection.Add(item);
        }

        public void Clear()
        {
            _collection.Clear();
        }

        public bool Contains(T item)
        {
            return _collection.Contains(item);
        }

        public void CopyTo(T[] array, int arrayIndex)
        {
            _collection.CopyTo(array, arrayIndex);
        }

        public int Count
        {
            get { return _collection.Count; }
        }

        public bool IsReadOnly
        {
            get { return ((ICollection<T>)_collection).IsReadOnly; }
        }

        public bool Remove(T item)
        {
            return _collection.Remove(item);
        }
        // ******************************************************************** 
        // End ICollection<T> Implementation
        // ******************************************************************** 

        // ******************************************************************** 
        // Begin IList<T> Implementation
        // ******************************************************************** 
        public int IndexOf(T item)
        {
            return _collection.IndexOf(item);
        }

        public void Insert(int index, T item)
        {
            _collection.Insert(index, item);
        }

        public T this[int index]
        {
            get { return _collection[index]; }
            set { _collection[index] = value; }
        }

        public void RemoveAt(int index)
        {
            _collection.RemoveAt(index);
        }
        // ******************************************************************** 
        // End IList<T> Implementation
        // ******************************************************************** 

        // ******************************************************************** 
        // Begin IEnumberable<T> Implementation
        // ******************************************************************** 
        public IEnumerator<T> GetEnumerator()
        {
            return _collection.GetEnumerator();
        }
        // ******************************************************************** 
        // End IEnumberable<T> Implementation
        // ******************************************************************** 

        // ******************************************************************** 
        // Begin Explicit ICollection Implementation
        // ******************************************************************** 
        int ICollection.Count
        {
            get { return ((ICollection)_collection).Count; }
        }

        void ICollection.CopyTo(Array array, int index)
        {
            ((ICollection)_collection).CopyTo(array, index);
        }

        bool ICollection.IsSynchronized
        {
            get { return ((ICollection)_collection).IsSynchronized; }
        }

        object ICollection.SyncRoot
        {
            get { return ((ICollection)_collection).IsSynchronized; }
        }
        // ******************************************************************** 
        // End Explicit ICollection Implementation
        // ******************************************************************** 

        // ******************************************************************** 
        // Begin Explicit IEnumerable Implementation
        // ******************************************************************** 
        IEnumerator IEnumerable.GetEnumerator()
        {
            return ((IEnumerable)_collection).GetEnumerator();
        }
        // ******************************************************************** 
        // End Explicit IEnumerable Implementation
        // ******************************************************************** 

        // ******************************************************************** 
        // Begin Explicit IList Implementation
        // ******************************************************************** 
        int IList.Add(object value)
        {
            return ((IList)_collection).Add(value);
        }

        void IList.Clear()
        {
            ((IList)_collection).Clear();
        }

        bool IList.Contains(object value)
        {
            return ((IList)_collection).Contains(value);
        }

        int IList.IndexOf(object value)
        {
            return ((IList)_collection).IndexOf(value);
        }

        void IList.Insert(int index, object value)
        {
            ((IList)_collection).Insert(index, value);
        }

        bool IList.IsFixedSize
        {
            get { return ((IList)_collection).IsFixedSize; }
        }

        bool IList.IsReadOnly
        {
            get { return ((IList)_collection).IsReadOnly; }
        }

        void IList.Remove(object value)
        {
            ((IList)_collection).Remove(value);
        }

        void IList.RemoveAt(int index)
        {
            ((IList)_collection).RemoveAt(index);
        }

        object IList.this[int index]
        {
            get
            {
                return ((IList)_collection)[index];
            }
            set
            {
                ((IList)_collection)[index] = value;
            }
        }
        // ******************************************************************** 
        // End Explicit IList Implementation
        // ******************************************************************** 
    }
}
